
//***************************************************************************
//                           Various "small" classes
//***************************************************************************
//  Copyright (C):
//***************************************************************************
//CVSId: "@(#)$Id: ColObj.h,v 1.10 2004/06/09 12:23:18 weller Exp $"
//***************************************************************************


#ifndef ColObj_H
#define ColObj_H
#if defined(__sgi) || defined(_WIN32)
#pragma once
#endif

//---------------------------------------------------------------------------
//  Includes
//---------------------------------------------------------------------------

#include <vector>

#include <col_import_export.h>
#include <ColDopTree.h>
#include <ColBoxtree.h>
#include <ColConvexHull.h>
#include <ColGridObj.h>
#include <ColGeometry.h>


namespace col {

//---------------------------------------------------------------------------
//  Forward References
//---------------------------------------------------------------------------

class Matrix;
class MatrixCell;
class ColPair;


//***************************************************************************
//  ColObj
//***************************************************************************

class COL_EXPORTIMPORT ColObj
{

	friend class Matrix;
	friend class MatrixCell;
	friend class ColPair;

public:

	ColObj();
	ColObj( const ColID objID, const ColGeometry* geom,
			bool flexible, bool stationary,
			bool compute_hull, AlgoE algo, Grid *grid,
			bool show_hull = false );
	virtual ~ColObj() throw();

	ColObj( const ColObj &source );
	void operator = ( const ColObj &source );

	void updateBBox( void );
	bool bboxIntersects( ColObj* );
	bool setTransMatrix( const Matrix4* );
	bool hasMoved( unsigned int global_cycle );
    void setMoved( unsigned int global_cycle );

	const char * getName( void ) const;
	ColID getID( void ) const;

	void setActive( bool active );
    bool isActive() const;
	void setFlexible( bool flexible );
	void setStationary( bool stationary );

	static ColObj* find( vector<ColObj*> *colobjs, const ColID objID );

    void SetGridObj( Grid *grid );
    GridObj* GetGridObj( void );
	void updateGrid ( void );

	//void setTransMatrix( const Matrix4 &tran );

	//const Matrix4 * getTransMatrixPtr() { return & m_curr_matr; }
protected:

	/// Used to remove an object temporarily from collision checks
	bool m_active;

	/// Set if the object deforms
	bool m_flexible;

	/// Set if the object doesn't move
    bool m_stationary;

	/// DOP tree of this obj
	const DopTree *m_doptree;

	/// Boxtree of this obj
	const Boxtree *m_boxtree;

	/// The actual "collidable" object
	const ColGeometry *m_geom;
	//const Matrix4 * m_tran;  // => describe the tranlation about the obj, should be real-time updated in the application phase

	/// The toWorld matrix of node as of last frame
	const Matrix4 *m_old_matr;

	/// The current toWorld matrix as of start of current cycle
	const Matrix4 *m_cur_matr;

	/// BoundingBox
	REAL m_bmin[3];
	REAL m_bmax[3];

    ///
	vector<const Pnt3Array *> points;
	
	// The name of the colobj
	//const char *m_name;
	
	// The id of the colobj
	ColID m_objID;

	/** row/column index into col. interest matrix
	 * If @a col_matr_idx < 0, then the ColObj is not valid.
	 * However, this should @e never happen!
	 */
	int m_col_matr_idx;

	/** Flags whether or not obj has moved since last frame.
	 * Is valid only if @a cycle == @a coll::Cycle
	 */
	bool m_has_moved;
	bool m_first_moved_check;
	unsigned int m_cycle;

	/// the convex hull of @a geom
	ConvexHull m_hull;

	//pointer to GridObj if grid is used, else NULL
	GridObj *m_gridobj;

};



//***************************************************************************
//  ColPair
//***************************************************************************

class COL_EXPORTIMPORT ColPair
{

public:

	ColPair();
	ColPair( ColObj *p, ColObj *q );
	ColPair( const ColPair &source );
	void operator = ( const ColPair &source );
	virtual ~ColPair() throw();

	ColObj* p( void ) const;
	ColObj* q( void ) const;

protected:

	/// the two ColObj's a ColPair consists of
	ColObj *m_p, *m_q;

};



//**************************************************************************
// MatrixCell
//**************************************************************************

class COL_EXPORTIMPORT MatrixCell
{
public:

	MatrixCell( const ColObj *colobj1, const ColObj *colobj2 );

	void addCallback(Callback *callback );
	void callCallbacks( void ) const;

	bool check( bool use_hulls, bool verb_print=false );

protected:

	/// positive collision callbacks
	vector<Callback*>	m_callback;

	/// the two collision objects of this cell
	const ColObj *const m_colobj1;
	const ColObj *const m_colobj2;

	/// the maximum level of detection of all callbacks of this cell
	LevelOfDetectionE m_level;

	/// the seprating plane of the convex hulls ColObj::hull
	SepPlane m_sep_plane;

	/// Collision data for collision callback and internal usage
	Data m_data;

    ///
    bool m_allpolygons;
};



//***************************************************************************
//  Matrix
//***************************************************************************

class COL_EXPORTIMPORT Matrix
{
public:

	Matrix( unsigned int numcolobjs = 50 );

	void addObj( ColObj *obj );
	void addCallback( Callback *callback, vector<ColObj*> *colobjs );

	MatrixCell* getCell( const ColPair &pair ) const;
	MatrixCell* createCell( const ColObj *obj1, const ColObj *obj2 );

	bool check( const ColPair &pair, bool use_hulls, AlgoE algo, bool verb_print=false ) const;
	void callCallbacks( const ColPair &pair ) const;

	bool isConsistent( vector<ColObj> *colobjs ) const;

protected:

	/// one row of the collision interest matrix (rows have different length)
	typedef vector<MatrixCell*> m_Row;

	/// the raison d'etre
	vector<m_Row> m_m;

	explicit Matrix( const Matrix &source );
    Matrix& operator = ( const Matrix &source );

};

} // namespace col

#endif // ColObj_H 
